﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using Microsoft.Win32;
using System.Windows;
using System.Xml;
using System.Windows.Media.Imaging;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Controls;

namespace SHomeWorkshop.LunarMind.Commands
{
    /// <summary>
    /// 以此类为模板，制作自定义命令类
    ///     共需要修改１０处！！！
    /// ==============================
    /// 
    /// 在同一级别向下平移命令。
    /// ★①，修改类名。
    /// </summary>
    public static class MoveDownBetweenSameLevelCommand
    {
        private static RoutedUICommand routedUICmd;//创建私有字段

        public static RoutedUICommand RoutedUICmd//创建只读静态属性
        {
            get { return routedUICmd; }
        }

        /// <summary>
        /// ★②，修改静态构造方法名。
        /// </summary>
        static MoveDownBetweenSameLevelCommand()//类型构造器
        {
            //★③，修改两个字符串参数名。★④以及第三个参数的类型名。
            routedUICmd = new RoutedUICommand(
                "MoveDownBetweenSameLevelCommand",
                "MoveDownBetweenSameLevelCommand",
                typeof(MoveDownBetweenSameLevelCommand),//创建RoutedUICommand对象
                null);

            cmdBinding.Command = routedUICmd;
            cmdBinding.CanExecute += new CanExecuteRoutedEventHandler(cmdBinding_CanExecute);
            cmdBinding.Executed += new ExecutedRoutedEventHandler(cmdBinding_Executed);
        }

        private static CommandBinding cmdBinding = new CommandBinding();

        public static CommandBinding CmdBinding
        {
            get { return cmdBinding; }
        }

        static void cmdBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            //★⑦，修改此方法的实现。

            MoveDown();
        }

        public static void MoveDown()
        {
            if (Globals.MainWindow.SelectedTitleImage != null)
            {
                StackPanel sp = Globals.MainWindow.SelectedTitleImage.Parent as StackPanel;
                if (sp != null && sp.Children.IndexOf(Globals.MainWindow.SelectedTitleImage) < (sp.Children.Count - 1))
                {
                    MoveSelectedTitleImageDown();
                    return;
                }
            }

            MoveTitleDownBetweenSameLevel();
        }

        private static void MoveSelectedTitleImageDown()
        {
            var selTitleImage = Globals.MainWindow.SelectedTitleImage;
            if (selTitleImage == null) return;

            Title title = selTitleImage.MasterTitle;
            if (title == null) return;

            XmlNode imgSetNode = title.XmlData.SelectSingleNode("ImageSet");
            if (imgSetNode == null)
            {
                imgSetNode = title.XmlData.AppendXml("<ImageSet/>");
            }

            int oldIndex = title.ImgStackPanel.Children.IndexOf(selTitleImage);
            int newIndex = oldIndex + 1;

            var deletedXmlText = selTitleImage.XmlData.OuterXml;

            ModifingItem mi = new ModifingItem()
            {
                IsNeedRefreshTitleAndLinesLocation = false,
                ModifingName = "标题图像下移",
                OldSelectedTitleID = title.ID,
                NewSelectedTitleID = title.ID,
            };

            Action actDeleteTitleImage = new Action(selTitleImage.ID, oldIndex,
                selTitleImage.GetType().Name, "DeleteTitleImage",
                selTitleImage.XmlData.OuterXml, null, ActionType.DeleteTitleImage, title.ID);

            //Action actDelImg = new Action(ti.ID, ti.Index, ti.GetType().Name, "DeleteTitleImage",
            //    ti.XmlData.OuterXml, null, ActionType.DeleteTitleImage, masterTitle.ID);

            title.ImgStackPanel.Children.Remove(selTitleImage);
            title.ImageSetNode?.RemoveChild(selTitleImage.XmlData);
            mi.Add(actDeleteTitleImage);
            mi.OldSelectedTitleImageID = selTitleImage.ID;

            selTitleImage.RebuildANewID();

            Action actInsertTitleImage = new Action(selTitleImage.ID, newIndex,
                selTitleImage.GetType().Name, "InsertTitleImage",
                null, selTitleImage.XmlData.OuterXml, ActionType.InsertTitleImage, title.ID);

            title.ImgStackPanel.Children.Insert(newIndex, selTitleImage);
            title.ImageSetNode?.InsertAt(newIndex, selTitleImage.XmlData);
            mi.Add(actInsertTitleImage);
            mi.NewSelectedTitleImageID = selTitleImage.ID;

            title.Editor.Do(mi);
            title.Editor.IsModified = true;
            title.Editor.SelectedTitleImage = selTitleImage;
            //title.Editor.RefreshTitleAndLinesLocation();

            selTitleImage.IsSelected = true;
            return;
        }

        /// <summary>
        /// 此方法是调用DeleteCommand的Delete来实现。
        /// </summary>
        internal static void MoveTitleDownBetweenSameLevel()
        {
            if (Globals.SelectedTitlesList == null)
            {
                MessageBox.Show("请先选中一个标题！", Globals.AppName,
                    MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            if (Globals.SelectedTitlesList.Count != 1)
            {
                MessageBox.Show("请先选中【一个】标题！", Globals.AppName,
                       MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            Title curTitle = Globals.SelectedTitlesList[0];

            if (curTitle == Globals.MainWindow.RootTitle)
            {
                MessageBox.Show("根标题不能上下平移！", Globals.AppName,
                       MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            Title higherTitle = curTitle.GetHigherLvelTitle();
            if (higherTitle == null)
            {
                MessageBox.Show("发生意外，没有找到上级标题，无法继续平移！", Globals.AppName,
                       MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            //如果是一级标题因为分左右，所以比较麻烦。
            if (higherTitle == Globals.MainWindow.RootTitle)
            {
                List<Title> brothers = higherTitle.GetLowerLevelTitles();
                if (brothers == null || brothers.Count <= 0 ||
                    brothers.Contains(curTitle) == false)
                {
                    MessageBox.Show("发生意外，没有找到同级标题，无法继续平移！", Globals.AppName,
                       MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }

                //同侧第一个索引比当前标题大的。
                Title destTitle = null;

                for (int i = curTitle.Index + 1; i <= brothers.Count - 1; i++)
                {
                    Title tmp = brothers[i];
                    if (tmp.Direction == curTitle.Direction && tmp.Index > curTitle.Index)
                    {
                        destTitle = tmp;
                        break;
                    }
                }

                if (destTitle != null)
                {
                    int oldIndex = curTitle.Index;
                    int destIndex = destTitle.Index;

                    //如果找到，就交换索引。
                    ModifingItem mi = new ModifingItem()
                    {
                        IsNeedRefreshTitleAndLinesLocation = true,
                        ModifingName = "在同级向下平移标题"
                    };

                    Action actIndexCur = new Action(curTitle.ID, curTitle.Index, curTitle.GetType().Name,
                        "Index", oldIndex.ToString(), destIndex.ToString());
                    curTitle.Index = destIndex;

                    mi.Add(actIndexCur);

                    Action actIndexDest = new Action(destTitle.ID, destIndex, destTitle.GetType().Name,
                        "Index", destIndex.ToString(), oldIndex.ToString());
                    destTitle.Index = oldIndex;

                    mi.Add(actIndexDest);

                    Globals.MainWindow.Do(mi);
                    Globals.MainWindow.IsModified = true;
                    Globals.MainWindow.RefreshTitleAndLinesLocation();
                }

                return;//找不到就算。
            }
            else
            {
                //其它级别比较简单——直接比较索引就是了。

                List<Title> brothers = higherTitle.GetLowerLevelTitles();
                if (brothers == null || brothers.Count <= 0 ||
                    brothers.Contains(curTitle) == false)
                {
                    MessageBox.Show("发生意外，没有找到同级标题，无法继续平移！", Globals.AppName,
                       MessageBoxButton.OK, MessageBoxImage.Warning);
                    return;
                }

                //同侧第一个索引比当前标题大的。
                Title destTitle = null;

                for (int i = curTitle.Index + 1; i <= brothers.Count - 1; i++)
                {
                    Title tmp = brothers[i];
                    if (tmp.Index > curTitle.Index)
                    {
                        destTitle = tmp;
                        break;
                    }
                }

                if (destTitle != null)
                {
                    int oldIndex = curTitle.Index;
                    int destIndex = destTitle.Index;

                    //如果找到，就交换索引。
                    ModifingItem mi = new ModifingItem()
                    {
                        IsNeedRefreshTitleAndLinesLocation = true,
                        ModifingName = "在同级向下平移标题"
                    };

                    Action actIndexCur = new Action(curTitle.ID, curTitle.Index, curTitle.GetType().Name,
                        "Index", oldIndex.ToString(), destIndex.ToString());
                    curTitle.Index = destIndex;

                    mi.Add(actIndexCur);

                    Action actIndexDest = new Action(destTitle.ID, destIndex, destTitle.GetType().Name,
                        "Index", destIndex.ToString(), oldIndex.ToString());
                    destTitle.Index = oldIndex;

                    mi.Add(actIndexDest);

                    Globals.MainWindow.Do(mi);
                    Globals.MainWindow.IsModified = true;
                    Globals.MainWindow.RefreshTitleAndLinesLocation();
                }

                return;//找不到就算。
            }
        }

        static void cmdBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            //★⑧，修改此方法的实现。

            if (Globals.MainWindow.SelectedTitleImage != null)
            {
                StackPanel sp = Globals.MainWindow.SelectedTitleImage.Parent as StackPanel;
                if (sp != null && sp.Children.IndexOf(Globals.MainWindow.SelectedTitleImage) < (sp.Children.Count - 1))
                {
                    e.CanExecute = true; return;
                }
            }

            if (Globals.SelectedTitlesList == null)
            {
                e.CanExecute = false; return;
            }

            if (Globals.SelectedTitlesList.Count != 1)
            {
                e.CanExecute = false; return;
            }

            Title t = Globals.SelectedTitlesList[0];

            if (t == Globals.MainWindow.RootTitle)
            {
                e.CanExecute = false; return;
            }

            Title higherTitle = t.GetHigherLvelTitle();
            if (higherTitle == null)
            {
                e.CanExecute = false; return;
            }

            //如果是一级标题因为分左右，所以比较麻烦。
            if (higherTitle == Globals.MainWindow.RootTitle)
            {
                List<Title> brothers = higherTitle.GetLowerLevelTitles();
                if (brothers == null || brothers.Count <= 0 ||
                    brothers.Contains(t) == false)
                {
                    e.CanExecute = false; return;
                }

                //得找出同侧的最大索引。
                int maxIndex = -1;
                foreach (Title tmp in brothers)
                {
                    if (tmp.Direction == t.Direction && tmp.Index > maxIndex)
                    {
                        maxIndex = tmp.Index;
                    }
                }

                if (maxIndex > t.Index)
                {
                    e.CanExecute = true;
                }
                else e.CanExecute = false;
            }
            else
            {
                //其它级别比较简单——直接比较索引就是了。

                //不能是最后一个。
                List<Title> brothers = higherTitle.GetLowerLevelTitles();
                if (brothers == null || brothers.Count <= 0 ||
                    brothers.Contains(t) == false)
                {
                    e.CanExecute = false; return;
                }

                if (t.Index < brothers.Count - 1)
                {
                    e.CanExecute = true;
                }
                else
                {
                    e.CanExecute = false;
                }
            }
        }
    }
}
